#include "GBusyWait.h"
#include "GThread.h"

#include <intrin.h>
#pragma intrinsic( _mm_pause )

namespace GThread
{
	static const GSize LoopCount = 16;

	inline static void Pause(GSize Count)
	{
		for (GSize I = 0; I < Count; ++I)
		{
			_mm_pause();
		}
	}

	GBusyWait::GBusyWait()
	{
		Counter = 1;
		StopAt = LoopCount;
	}

	GBusyWait::GBusyWait(GSize StopCount)
	{
		Counter = 1;
		StopAt = StopCount;
	}

	GBusyWait::~GBusyWait()
	{
		
	}

	void GBusyWait::Reset()
	{
		Counter = 1;
	}

	void GBusyWait::Wait()
	{
		if (Counter < StopAt)
		{
			Pause(Counter);
			Counter *= 2;
		}
		else
		{
			GThread::SwitchThread();
		}
	}

	bool GBusyWait::WaitNoYield()
	{
		if (Counter < StopAt)
		{
			Pause(Counter);
			Counter *= 2;
			return true;
		}
		else
		{
			return false;
		}
	}

}; // namespace GThread